/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GUI;

import MiddleLayer.Card;
import MiddleLayer.GameRules;
import MiddleLayer.OtherClass.CommandStruct.MessageType;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import javax.swing.ImageIcon;
import javax.swing.JButton;

/**
 *
 * @author Green
 */
public class Hearts extends Game {

    //private BufferedImage background;
    //private BufferedImage img;
//    private ClientProcessing client = new ClientProcessing();
    //Những trạng thái theo từng giai đoạn:
    //khởi đầu(thiết lập các biến cần thiết cho 1 ván mới),
    //chia bài,
    //pass bài,
    //chơi bài(đang trong quá trình chơi),
    //kết thúc (hiện điểm,hiện bài bị nhận,hiện người thua nếu có).
    public enum GameState {

        Begining, Dealing, Passing, Playing, Ending
    };

    public enum PlayerState {

        DoNothing, Pass, PlayCard
    };
    private Banker banker;
    private GameState currentState;
    private PlayerState playerState;
    private GamblerManager gManager;
    public static MotionManager motionManager = new MotionManager();
    public boolean isFirstTurn = false;
    private boolean isFinishedTask = true;
    ArrayList<ImageIcon> lstIconForPassButton = new ArrayList<ImageIcon>();

    public GameState getCurrentState() {
        return currentState;
    }

    public void setCurrentState(GameState currentState) {
        this.currentState = currentState;
        this.isFinishedTask = false;
        if (currentState == GameState.Passing) {
            this.playerState = PlayerState.Pass;
        } else {
            if (currentState == GameState.Playing) {
                this.playerState = PlayerState.PlayCard;
            } else {
                this.playerState = PlayerState.DoNothing;
            }
        }
    }

    public PlayerState getPlayerState() {
        return playerState;
    }

    public void setPlayerState(PlayerState playerState) {
        this.playerState = playerState;
    }

    public Hearts() {
        motionManager.clear();
    }

    @Override
    public void init() {
        this.gp.setSize(1024, 540);
        this.loadResources();
        this.gManager = new GamblerManager(this.gp.getWidth(), this.gp.getHeight());
        this.banker = new Banker(this.gp);
        this.currentState = GameState.Begining;
        this.playerState = PlayerState.DoNothing;
        this.gp.showPassButton(false);
    }

    @Override
    public void updateGame() {
        motionManager.update();

        if (this.currentState == GameState.Begining) {
        }

        if (this.currentState == GameState.Dealing) {
            if (this.isFinishedTask) {
                return;
            }
            System.out.println("Dealing : " + banker.countAvailableCard());
            if (banker.countAvailableCard() == 0) {
                //this.clientMessenger.finishTask(currentState);
                this.isFinishedTask = true;
            }
        }

        if (this.currentState == GameState.Passing) {
            if (this.isFinishedTask) {
                return;
            }

            if (this.gManager.getMainPlayer().isReadyToPass()) {
                if (!this.gp.isPassButtonEnable()) {
                    java.awt.EventQueue.invokeLater(new Runnable() {

                        public void run() {
                            gp.enablePassButton(true);
                        }
                    });
                }

            } else {
                if (this.gp.isPassButtonEnable()) {
                    java.awt.EventQueue.invokeLater(new Runnable() {

                        public void run() {
                            gp.enablePassButton(false);
                        }
                    });
                }
            }
        }

        if (this.currentState == GameState.Playing) {
            if (this.isFinishedTask) {
                return;
            }
        }

        if (this.currentState == GameState.Ending) {
            if (this.isFinishedTask) {
                return;
            }
        }
    }

    @Override
    public void paintGame(Graphics g) {
//        throw new UnsupportedOperationException("Not supported yet.");
        Color c = new Color(0, 160, 0);
        Color oldColor = g.getColor();
        g.setColor(c);
        g.fillRect(0, 0, this.gp.getWidth(), this.gp.getHeight());
        g.setColor(oldColor);

        if (this.currentState == GameState.Begining) {
        }

        if (this.currentState == GameState.Dealing) {
            this.banker.drawDecksBackFace(g);
            this.gManager.drawAllsCards(g);
        }

        if (this.currentState == GameState.Passing) {
            this.gManager.drawAllsCards(g);
        }

        if (this.currentState == GameState.Playing) {
            this.banker.drawOnBoardCards(g);
            this.gManager.drawAllsCards(g);
        }

        if (this.currentState == GameState.Ending) {
            this.gManager.drawAllsTakenCards(g);
        }

        this.gManager.drawAllsNames(g);
        motionManager.draw(g);
    }

    //Bắt sự kiện chuột xảy ra với game
    @Override
    public void mouseClicked(MouseEvent e) {
        Point p = e.getPoint();
//        super.mouseClicked(e);
        //nêu server có lệnh là pass
        if (this.playerState == PlayerState.Pass) {
            //cho phép player tương tác với card.
            Gambler player = this.gManager.getMainPlayer();
            player.selectCardToPass(p);
        }

        //nếu server có lệnh là đánh 1 lá bài
        if (this.playerState == PlayerState.PlayCard) {
            Gambler player = this.gManager.getMainPlayer();
            GUICard selected = player.getHitCard(p);

            if(selected == null)
                return;

            if (isFirstTurn) {
                //Kiểm tra xem có hợp lệ ko
                int cardID = Card.convertCardGUI_IDToCard_ID(selected.toCardID());
                if(this.clientMessenger.gameRules.isLeadMovingValid(
                        cardID)
                        )
                {
                    //this.clientMessenger.sendToServer(this.gManager.player.getName(), selected.toCardID());
                    String content = Integer.toString(cardID);
                    this.clientMessenger.sendMessageToServer(MessageType.PlayCard, content);
                    isFirstTurn = false;
                }
            } else {
                int iCurrCardID = Card.convertCardGUI_IDToCard_ID(selected.toCardID());
                int iFirstCardID = Card.convertCardGUI_IDToCard_ID(banker.getFirstCardOnBoard().toCardID());
                if(this.clientMessenger.gameRules.isMovingValid(iCurrCardID, iFirstCardID, player.getGamblerCards()))
                {
                    this.clientMessenger.sendMessageToServer(MessageType.PlayCard, Integer.toString(iCurrCardID));
                }

//               if (this.clientMessenger.checkRules(selected.toCardID(), banker.getFirstCardOnBoard().toCardID(), player.getGamblerCards())) {
//                    this.clientMessenger.sendToServer(this.gManager.player.getName(), selected.toCardID());
//                }
            }
        }
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof JButton) {

            //this.clientMessenger.finishTask(currentState);
            this.setPlayerState(PlayerState.DoNothing);
            this.isFinishedTask = true;
            //hoàn thành nhiệm vụ thì disable nó đi
            JButton button = (JButton) e.getSource();
            button.setEnabled(false);
        }
    }

    //Lấy ảnh cho việc tạo card
    public void loadResources() {
        BufferedImage cardsuittexture = ImageUtility.loadImageFromResource_("Images/StandardDeck.gif");
        BufferedImage backfacetexture = ImageUtility.loadImageFromResource_("Images/backfacecard.png");//Toolkit.getDefaultToolkit().getImage((getClass().getResource("Images/backfacecard.png")));
        GUICard.width = 71;
        GUICard.height = 96;
        Deck.setWidth(GUICard.width);
        Deck.setHeight(GUICard.height);
        Deck.backfacetexture = backfacetexture;
        Deck.cardsuittexture = cardsuittexture;

        for (int i = 0; i < 3; i++) {
            ImageIcon icon = new ImageIcon(ImageUtility.getInstance().loadImageFromResource_("Images/pass_arrow_small_" + i + ".png"));
            this.lstIconForPassButton.add(icon);
        }
    }

    public void initAllsClients(String clientName, ArrayList<String> lstNames) {
        this.gManager.initPlayers(clientName, lstNames);
    }
    
    //Thục hiện chia bài
    public void dealCardToGambler(int rank, int suit, String name) {
        Gambler gambler = this.gManager.getGambler(name);
        this.banker.dealCard(rank, suit, gambler);
    }

    public void sendTakenCardToGambler(int rank, int suit, String name) {
        Gambler gambler = this.gManager.getGambler(name);
        this.banker.sendCardToLostGambler(rank, suit, gambler);
    }

    public void sendTakenCardsToGambler(ArrayList<Integer> guiIDList,String name) {
        Gambler gambler = this.gManager.getGambler(name);
        for (int i = 0; i < guiIDList.size(); i++) {
            Integer guiID = guiIDList.get(i);
            int rank = guiID % 13;
            int suit = guiID / 13;
            this.banker.sendCardToLostGambler(rank, suit, gambler);
        }

        //this.clientMessenger.finishTask(currentState);
    }

    public void selectCardsToPass(int rank, int suit, String name) {
        Gambler gambler = this.gManager.getGambler(name);
        if (gambler == this.gManager.player) {
            return;
        }
        gambler.selectCardToPass(rank, suit);
    }

    public void passSelectedCards(int direction) {
        this.gManager.passCards(direction);
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                gp.showPassButton(false);
            }
        });
        //this.clientMessenger.finishTask(currentState);
    }

    public void playCard(int rank, int suit, String name) {
        Gambler gambler = this.gManager.getGambler(name);
        gambler.playCard(rank, suit, banker);
        this.isFirstTurn = false;
        //this.clientMessenger.finishTask(currentState);
    }

    public void prepareForNextGame() {
        this.banker.reset();
        this.gManager.resetAllsGamblers();
        this.setCurrentState(GameState.Begining);
        //this.clientMessenger.finishTask(currentState);
    }

    public void prepareToDeal() {
        this.setCurrentState(GameState.Dealing);
        //this.clientMessenger.finishTask(currentState);
    }

    //direction = 0,1,2 <-> trái,phải,trên
    public void prepareToPass(int direction) {
        if (direction < 0 || direction > 2) {
            return;
        }
        this.setCurrentState(GameState.Passing);
        this.gp.button.setIcon(this.lstIconForPassButton.get(direction));
        this.gp.showPassButton(true);
//        switch (direction) {
//            case 0:{
//                break;
//            }
//            case 1:
//                break;
//            case 2:
//                break;
//        }
        //clientMessenger.finishTask(currentState);
    }

    public void prepareToPlay() {
        this.setCurrentState(GameState.Playing);
        this.gp.showPassButton(false);
        this.isFirstTurn = true;
        //this.clientMessenger.finishTask(currentState);
    }

    public void prepareToEnd() {
        this.setCurrentState(GameState.Ending);
        //this.clientMessenger.finishTask(currentState);
    }

    public void waitClientAction() {
        this.isFinishedTask = false;
        this.playerState = PlayerState.PlayCard;
    }
}
